﻿/**************************************************************

项目名称 :MF数据访问基础库
版权所有 (c) 2010 MFSoft
+-------------------------------------------------------------
项目: SQLServer数据库服务类


版本: 1


创建日期:2010-5-3


作者: 章称

+-------------------------------------------------------------
描述:z

更新:   2010-5-3

ToDo:

***************************************************************/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Reflection;

namespace MF.Data.ORMapping
{
    public class MFDataTrans
    {

        /// <summary>
        /// 根据Table返回对象集
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="ADataTable"></param>
        /// <returns></returns>
        public static  List<T> GetList<T>(DataTable ADataTable)
        {

            List<T> Entities = new List<T>();
            foreach(DataRow row in ADataTable.Rows)
            {
                T Entity = Activator.CreateInstance<T>();
                SetEntity<T>(Entity, row);
                Entities.Add(Entity);
                
            }
            return Entities;
        }

        /// <summary>
        /// 根据一行设置一个对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="Entity"></param>
        /// <param name="ADataRow"></param>
        private static void  SetEntity<T>(T Entity, DataRow ADataRow)
        {
            Type type = typeof(T);
            foreach (DataColumn col in ADataRow.Table.Columns)
            {

                object value = ADataRow[col];
                PropertyInfo pInfo=type.GetProperty(col.ColumnName);
                if (pInfo != null)
                {
                    
                    pInfo.SetValue(Entity, value, null);
                }
            }
        }

        /// <summary>
        /// 根据对象集合返回DataSet
        /// </summary>
        /// <param name="AList"></param>
        /// <returns></returns>
        public static DataSet GetDataSet<T>(List<T> AList)
        {
            if (AList.Count == 0) return null;

            Type type = typeof(T);
            DataSet ds = new DataSet();
            T Entity=AList[0];
            SetDataSetScheme(ds, Entity);
            foreach(T AItem in AList)
            {
                DataRow ARow=ds.Tables[0].NewRow(); 

                foreach(DataColumn col in ARow.Table.Columns)
                {
                    PropertyInfo pInfo=type.GetProperty(col.ColumnName);

                    ARow[col.ColumnName] = pInfo.GetValue(AItem,null);
                }

            }
            return ds;
        }

        /// <summary>
        /// 创建DataSet结构
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="ADataSet"></param>
        /// <param name="Entity"></param>
        private static void SetDataSetScheme<T>(DataSet ADataSet,T Entity)
        {
            Type type = typeof(T);
            
            string sTableName=type.Name;

            foreach(object AClassAtt  in type.GetCustomAttributes(false))
            {
                if (AClassAtt is MFTableAttribute)
                {
                    sTableName=(AClassAtt as MFTableAttribute).TableName;
                }
            }

            DataTable tb=ADataSet.Tables.Add(sTableName);


            foreach(PropertyInfo pInfo in type.GetProperties())
            {
                
                DataColumn  col=tb.Columns.Add();
                col.ColumnName=pInfo.Name;
               
                foreach(object APropertyAtt  in pInfo.GetCustomAttributes(false))
                {
                    if (APropertyAtt is MFFieldAttribute)
                    {
                        MFFieldAttribute AFieldAttribute = (MFFieldAttribute)APropertyAtt;
                        if (AFieldAttribute.FieldName != string.Empty)
                            col.ColumnName = AFieldAttribute.FieldName;

                        col.AllowDBNull = AFieldAttribute.IsNullable;

                        if (AFieldAttribute.DataType != null)
                            col.DataType = AFieldAttribute.DataType;
                        else
                            col.DataType = pInfo.GetType();
                        if (AFieldAttribute.MaxLength != -1)
                            col.MaxLength = AFieldAttribute.MaxLength;
                    }
                }

           
            }

        }
    }



    /// <summary>
    /// 表对象属性类
    /// </summary>
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]
    public class MFTableAttribute : Attribute
    {

        public string TableName { get; set; }
        public string Where { get; set; }
        public string OrderBy { get; set; }

		public MFTableAttribute() { }

		public MFTableAttribute(string sTableName)
		{
			TableName = sTableName;
		}
    }

    /// <summary>
    /// 字段对象属性类
    /// </summary>
    [AttributeUsage(AttributeTargets.Property)]
	public class MFFieldAttribute : Attribute
	{
		private bool FIsChangeable;

		public string FieldName { get; set; }
		public object DefaultValue { get; set; }
		public bool IsPrimaryKey { get; set; }
		public bool IsNullable { get; set; }
		public bool IsDbGenerated { get; set; }
        public Type DataType { get; set; }
        public int MaxLength { get; set; }

		public bool IsChangeable
		{
			get
			{
				if (IsPrimaryKey || IsDbGenerated)
				{
					return false;
				}
                return FIsChangeable;
			}
            set { FIsChangeable = value; }
		}

        public MFFieldAttribute()
		{
			IsPrimaryKey = false;
			IsNullable = false;
			IsDbGenerated = false;
			IsChangeable = true;
            MaxLength = -1;
            DataType = null;
		}

        public MFFieldAttribute(string sFieldName):this()
        {
            FieldName = sFieldName;
        }
	}
}
